import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;

public class Parser {
    //先指定一个加载文档的路径
    private static final String INPUT_PATH = "D:\\Downloads\\java\\jdk-8u421-docs-all\\docs\\api\\";

    //创建一个Index实列
    private Index index = new Index();
    public void run() {
        //整个Parser类的入口

        //1.根据上面指定的路径，举出该路径中所有的文件(html). 这个过程需要把所有子目录中的文件都能获取到
        ArrayList<File> fileList = new ArrayList<>();
        enumFile(INPUT_PATH, fileList);
//         System.out.println(fileList);
//         System.out.println(fileList.size());

        // 2.针对上面罗列出的文件的路径，打开文件，读取文件内容，并进行解析，并构建索引.
        for (File f : fileList) {
            //通过这个方法来解析单个的HTML 文件
            System.out.println("开始解析: " + f.getAbsolutePath());
            parseHTML(f);
        }
        // 3.把在内存中构造好的索引数据结构，保存到指定的文件中
        index.save();
    }

    private void parseHTML(File f) {
        //1.解析出HTML的 标题
        String title = parseTitle(f);
        //2.解析出HTML 对应的URL
        String url = parseUrl(f);
        //3.解析出HTML 对应的正文（有了正文才有后续的描述）
        String content = parseContent(f);
        //4.把解析出来的这些信息，加入到索引当中
        index.addDoc(title, url, content);
    }

    public String parseContent(File f) {
        //  先按照一个字符一个字符的方式来读取，以<和> 来控制拷贝数据的开关
        try(FileReader fileReader = new FileReader(f)) {
            //加上一个是否要进行拷贝，开关
            boolean isCopy = true;
            //还得准备一个保存结果的 StringBuilder
            StringBuilder content = new StringBuilder();
            while (true){
                //注意，此处的read，返回值是一个int，而不是char
                //用int作为返回值，主要是为了表示一些非法情况
                //如果读到了文件末尾，继续读，就会返回-1
                int ret = fileReader.read();
                if(ret == -1){
                    //表示文件读完了
                    break;
                }
                //如果这个结果不是-1，那么就是一个合法的字符
                char c  = (char) ret;
                if(isCopy){
                    //如果是打开的状态，遇到普通字符就应该拷贝到StringBuilder中
                    if(c == '<'){
                        //关闭开关
                        isCopy = false;
                        continue;
                    }
                    if(c == '\n' || c == '\r'){
                        //为了去掉换行，把换行替换成空格
                        c = ' ';
                    }
                    //其他字符，直接拷贝即可，把结果拷贝到最终的StringBuilder中
                    content.append(c);
                }else{
                    //开关是关闭的状态，就暂时不拷贝，直到遇到>
                    if(c == '>'){
                        isCopy = true;
                    }
                }
            }

            return content.toString();
        } catch (IOException e) {
            //throw new RuntimeException(e);
            e.printStackTrace();
        }
        return "";
    }

    private String parseUrl(File f) {
        String part1 = "https://docs.oracle.com/javase/8/docs/api/";
        String part2 =  f.getAbsolutePath().substring(INPUT_PATH.length());
        return part1 + part2;
    }

    private String parseTitle(File f) {
        String name = f.getName();
        return name.substring(0, name.length() - ".html".length());
    }


    //第一个参数表示从哪个目录开始进行递归遍历
    //第二个参数表示递归得到的结果
    private void enumFile(String inputPath, ArrayList<File> fileList) {
        File rootPath = new File(inputPath);
        //listFiles 能够获取到rootPath 当前目录下所包含的文件/目录
        File[] files = rootPath.listFiles();
        for (File f : files) {
            //根据当前f的类型，来决定是否要递归
            //如果f是一个目录，就递归，继续寻找普通文件
            //如果f是一个普通文件，就add到fileList中
            if (f.isDirectory()) {
                enumFile(f.getAbsolutePath(), fileList);
            } else {
                if (f.getAbsolutePath().endsWith(".html")) {
                    fileList.add(f);
                }
            }
        }
    }


    public static void main(String[] args) {
        //通过main方法来实现整个制作索引的过程
        Parser parser = new Parser();
        parser.run();
    }
}
